/*
IM的消息协议的编解码实现。

编码 ：IMMessage -> TCP byte[]; 
解码 : TCP byte[] -> IMMessage；


日期          作者           说明
----------------------------------------
2018-08-29    lcl           源代码 ver 1.0
+

*/
package com.example.tang5.myapplication.im.Protocol;

import com.example.tang5.myapplication.im.IMMessage.IMMessage;
import com.example.tang5.myapplication.im.IMUtil.BytesConverter;

import java.nio.ByteBuffer;


/*
IM Ver1的通讯协议格式为：

Package Length  4 bytes，总数据包长  
Header Length   2 bytes，包头长度，固定值为10( Protocol Ver length + Command Tag length + Message ID Length)
Protocol Ver    2 bytes，版本协议号
Command Tag     4 bytes，消息命令
Message ID      4 bytes，消息ID
Body Datas      变长数据体，长度等于Package Length - Heaer Length

*/

//MessageEncoderVer1 ver 1版本的编解码器实现
public class MessageEncoderVer1 implements IMessageEncoder {
	//单例
	private static MessageEncoderVer1 inst;
	private ByteBuffer bf = null;

	public static MessageEncoderVer1 instance() {
		if (null == inst) {
			inst = new MessageEncoderVer1();
		}
		return inst;
	}

	//编码
	@Override
	public byte[] decode(IMMessage imMessage) {
		if (null == imMessage) {
			return null;
		}

		try {
			//byte[] bytes = new byte[imMessage.getPackageLength()];
			ByteBuffer bbf = ByteBuffer.allocate(imMessage.getPackageLength());

           /* Package Length  4 bytes，总数据包长
            Header Length   2 bytes，包头长度，固定值为10( Protocol Ver length + Command Tag length + Message ID Length)
            Protocol Ver    2 bytes，版本协议号
            Command Tag     4 bytes，消息命令
            Message ID      4 bytes，消息ID
            Body Datas      变长数据体，长度等于Package Length - Heaer Length*/

			bbf.putInt(imMessage.getPackageLength());
			bbf.putShort(imMessage.getHeaderLength());
			bbf.putShort(imMessage.getProtocolVer());
			bbf.putInt(imMessage.getCommandTag());
			bbf.putInt(imMessage.getMessageID());
			bbf.put(imMessage.getBody());

			return bbf.array();
		} catch (Exception e) {
			return null;//如果发生异常
		}
	}

	//解码
	@Override
	public IMMessage encode(byte[] messageBytes) {
		if (null == messageBytes) {
			return null;
		}

		try {
			IMMessage imMessage = new IMMessage();

			//总包长packageLength是自动计算，不需要写入;
			//包头长度headerLength是固定值，不需要写入；
			imMessage.setProtocolVer(BytesConverter.byte2ToShort(messageBytes, 6)); //协义版本号，第6字节开始
			imMessage.setCommandTag(BytesConverter.byte4ToInt(messageBytes, 8));    //command tag，第8字节开始
			imMessage.setMessageID(BytesConverter.byte4ToInt(messageBytes, 12));    //Message ID，第12字节开始

			//解析body，从16字节开始
			byte[] body = new byte[imMessage.getPackageLength() - imMessage.getHeaderLength()];
			System.arraycopy(messageBytes, 16, body, 0,
					imMessage.getPackageLength() - imMessage.getHeaderLength());
			imMessage.setBody(body);
			return imMessage;
		} catch (Exception e) {
			return null;//如果发生异常
		}
	}
}

